package com.ljcalc.business.components;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import com.ljcalc.business.components.requests.HistoryResultRequest;

public class ResultHistory extends AbstractResultHistory {
	
    private String filename = null;
    protected Properties properties = new Properties();	
	public static final String LATEST_RESULT_KEY = "LATEST_RESULT_KEY";
	
	public static final int SSL_TYPE = 1;
	public static final int SPTT_TYPE = SSL_TYPE*2;
	
	
	protected int latestyear = 0;
    protected int latestRound = 0;
    protected int latesttype = 0;
    
    protected static int HISTORY_TYPE = 0;
    
    

	protected ResultHistory(String defaultFileName, String fn){
		if(fn==null){
			setFilename(defaultFileName);
		}else{
			setFilename(fn);
		} 
		InputStream is = null;
		try {
			is = new FileInputStream(getFilename());
		} catch (FileNotFoundException e1) {


			File file = new File(getFilename());
    	    try {
				if (!file.isFile() && !file.createNewFile()){
				    throw new IOException("Error creating new file: " + file.getAbsolutePath());
				    }
		
        	    is = new FileInputStream(getFilename());
		
    		} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

        try {
        

        	if(is!=null){
        		getProperties().load(is);
        	}
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}
	
	public void setFilename(String filename) {
		this.filename = filename;
	}

	protected String getFilename(){
		return this.filename;
	}
	
	protected Properties getProperties(){
		return this.properties;
	}
	
	public Enumeration<Object> getAllKeys(){
		return properties.keys();
	}
	
    public List<Combination> getResults(String key) {
    	if(key.equals(LATEST_RESULT_KEY)){
    		return new LinkedList();
    	}
        return parseResults(properties.getProperty(key));
    }
    
    public boolean setResults(int type,int year, int round, List<Combination> results){
    	if(year>this.latestyear){
    		this.latestyear = year;
    	}
    	
    	if(year==this.latestyear&&round>this.latestRound){
    		this.latestRound = round;
    	}    	
    	
    	this.latesttype = type;
    	
    	String key = generateKey(type,year,round);
    	if(results==null){
    		System.out.println(key + " has problem");
    		return false;
    	}else{
    		properties.setProperty(key, results.toString());
    		System.out.println(key + " is set as property");
    		return true;
    	}
    }
    
	public HistoryResultRequest getLatestResultInRequest() {
		// TODO Auto-generated method stub
		String key = properties.getProperty(LATEST_RESULT_KEY);
		if(key==null){
			return null;
		}	
		return getResultInRequest(key);
	}
    
	public void save(boolean append){		
    	try {
    		OutputStream out = new FileOutputStream(getFilename(), append);
    		properties.setProperty(this.LATEST_RESULT_KEY, generateKey(this.latesttype, this.latestyear, this.latestRound));
			properties.store(out, new Date(System.currentTimeMillis()).toString());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public String generateKey(int type, int year, int week) {
		// TODO Auto-generated method stub
		return year+"_"+week+"_"+type;
	}
    
    /**
     * parse the result string into a list of combinations
     * @param result
     * @return
     */
    private List<Combination> parseResults(String result){
    	//first find the comma sign

	
		List<Combination> list = new LinkedList<Combination>();

		Combination comb = generateCombination(HISTORY_TYPE);
		int strHead = 0;
		for(int i=0;i<result.length();i++){
			if(Character.isWhitespace(result.charAt(i))||Character.isSpaceChar(result.charAt(i))
					||result.charAt(i)=='['||result.charAt(i)==']'||result.charAt(i)==','){
				if(strHead<i){
					comb.insertNumber(Long.parseLong((String) result.substring(strHead, i)));
					if(comb.isFull()){
						list.add(comb);
						comb = generateCombination(HISTORY_TYPE);
					}
					strHead=i+1;
				}else{
					strHead++;
				}
			}
			
			if(i==result.length()-1&&strHead<i){
				comb.insertNumber(Long.parseLong((String) result.substring(strHead, result.length())));
			}
		}

		
    	return list;
    }
    
    public static Combination generateCombination(int HISTORY_TYPE) {
		if(HISTORY_TYPE==SSL_TYPE){
			return new SSLCombination();
		}else if(HISTORY_TYPE==SPTT_TYPE){
			return new SPTTCombination();
		}
		
		return null;
		
	}

	/**
     * parse the key string into the history result request form
     * @param key
     * @return
     */
    public HistoryResultRequest getResultInRequest(String key){
		int startIndex =  0;
		int underScoreIndex = key.indexOf('_');
		int year = Integer.valueOf(key.substring(startIndex, underScoreIndex));
		startIndex = underScoreIndex;
		underScoreIndex = key.substring(startIndex+1,key.length()).indexOf('_') + startIndex+1;
		int round = Integer.valueOf(key.substring(startIndex+1, underScoreIndex));
		startIndex = underScoreIndex+1;
		int type = Integer.valueOf(key.substring(startIndex, key.length()));
    	return new HistoryResultRequest(type, year, round);
    }
}
